package com.zyq.bootbase.config;

import cn.hutool.core.util.StrUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.generator.config.rules.DbType;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.baomidou.mybatisplus.spring.boot.starter.SpringBootVFS;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Collections;

/**
 * JKhaled created by zyq@foxmail.com 2017/11/21
 * FOR : Mybatis-plus 核心配置
 */
@Data
@Configuration
@EnableConfigurationProperties(MybatisProperties.class)
@ConfigurationProperties(prefix = "spring.datasource")
@EqualsAndHashCode(callSuper = false)
public class MybatisPlusConfig extends WebMvcConfigurerAdapter {

  private String url;

  private String dbType;

  private String password;

  private String username;

  @Autowired(required = false)
  private Interceptor[] interceptors;

  @Autowired
  private MybatisProperties properties;

  @Autowired(required = false)
  private DatabaseIdProvider databaseIdProvider;

  @Autowired
  private ResourceLoader resourceLoader = new DefaultResourceLoader();

  /**
   * @Description : mybatis-plus SQL执行效率插件【生产环境可以关闭】
   */
  @Bean
  public PerformanceInterceptor performanceInterceptor() {
    return new PerformanceInterceptor();
  }

  /**
   * 配置DataSource
   *
   * @return
   * @throws SQLException
   */
  @Bean
  public DataSource dataSource() {
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setUrl(url);
    dataSource.setUsername(username);//用户名
    dataSource.setPassword(password);//密码
    dataSource.setInitialSize(2);
    dataSource.setMaxActive(20);
    dataSource.setMinIdle(0);
    dataSource.setMaxWait(60000);
    dataSource.setValidationQuery("SELECT 1");
    dataSource.setTestOnBorrow(false);
    dataSource.setTestWhileIdle(true);
    dataSource.setPoolPreparedStatements(false);
    if (StrUtil.isBlank(dbType)) {
      dataSource.setConnectionInitSqls(Lists.newArrayList("set names utf8mb4;"));
    }
    return dataSource;
  }

  /**
   * @Description : mybatis-plus分页插件
   * ---------------------------------
   */
  @Bean
  public PaginationInterceptor paginationInterceptor() {
    PaginationInterceptor page = new PaginationInterceptor();

    page.setDialectType(StrUtil.isBlank(dbType) ? DBType.MYSQL.name() : dbType);
    return page;
  }

  /**
   * 这里全部使用mybatis-autoconfigure 已经自动加载的资源。不手动指定
   * 配置文件和mybatis-boot的配置文件同步
   *
   * @return
   */
  @Bean
  public MybatisSqlSessionFactoryBean mybatisSqlSessionFactoryBean() {
    MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean();
    mybatisPlus.setDataSource(dataSource());
    mybatisPlus.setVfs(SpringBootVFS.class);
    if (StringUtils.hasText(this.properties.getConfigLocation())) {
      mybatisPlus.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
    }
    mybatisPlus.setConfiguration(properties.getConfiguration());
    if (!ObjectUtils.isEmpty(this.interceptors)) {
      mybatisPlus.setPlugins(this.interceptors);
    }
    // MP 全局配置，更多内容进入类看注释
    GlobalConfiguration globalConfig = new GlobalConfiguration();
    globalConfig.setDbType(StrUtil.isBlank(dbType) ? DBType.MYSQL.name() : dbType);
    // ID 策略 AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID") UUID->`3`("全局唯一ID")
    globalConfig.setIdType(0);
    mybatisPlus.setGlobalConfig(globalConfig);
    MybatisConfiguration mc = new MybatisConfiguration();
    mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
    mybatisPlus.setConfiguration(mc);
    if (this.databaseIdProvider != null) {
      mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider);
    }
    if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
      mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
    }
    if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
      mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
    }
    if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
      mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations());
    }
    return mybatisPlus;
  }

}
